/*
 * spi_io.c
 *
 *  Created on: Sep 30, 2013
 *      Author: Ken Arok
 */


#include "spi_io.h"

static spi_options_t spi_opt;

void spi_io_init(uint8_t _master_slave)
{
	/* Initialize SPI. */
	switch(_master_slave) {
		case CONFIG_SPI_MASTER:
			spi_master_init();
			spi_opt.master = _master_slave;
		break;

		case CONFIG_SPI_SLAVE:
			spi_slave_init();
			spi_opt.master = _master_slave;
		break;

		default: break;
	}
}

uint8_t spi_io_ctrl(io_port_t spiPort, io_request_code_t reqCode, void *pValue)
{
	uint8_t _ret_status = pdPASS;
	SPI_port_t _basePort;

	switch(spiPort) {
		case IOP_SPI1:
		case IOP_SPI2:
		case IOP_SPI3:
			_basePort = spiPort - IOP_SPI1;
			switch(reqCode) {
				case IORC_RESTART_MODULE:
					/* Initialize SPI. */
					if(spi_opt.master == CONFIG_SPI_MASTER) {
						spi_master_init();
					}
					else if(spi_opt.master == CONFIG_SPI_SLAVE) {
						spi_slave_init();
					}
				break;

				case IORC_SET_DEFAULT:
					spi_opt.master = CONFIG_SPI_MASTER;
					spi_opt.mode = CONFIG_SPI_MODE0;
					spi_opt.transfer_order = CONFIG_ORDER_MSB_FIRST;
					spi_setup(_basePort, (const spi_options_t *)&spi_opt);
				break;

				case IORC_SET_RX_TIMEOUT:
					spi_rx_timeout(_basePort, *(const uint32_t *)pValue);
				break;

				case IORC_SET_TRANSFER_POLLED:
					spi_tranfer_mode(_basePort, SPI_POLLED);
				break;

				case IORC_SET_TRANSFER_INTERRUPT:
					spi_tranfer_mode(_basePort, SPI_INTERRUPT);
				break;

				default:
					 _ret_status = pdFAIL;
				break;
			}
		break;

		default:
			_ret_status = pdFAIL;
		break;
	}

	return _ret_status;
}


uint8_t spi_io_open(io_port_t spiPort, const uint8_t flag)
{
	uint8_t _ret_status = pdFAIL;
	SPI_port_t _basePort;

	switch(spiPort) {
		case IOP_SPI1:
		case IOP_SPI2:
		case IOP_SPI3:
			_basePort = spiPort - IOP_SPI1;
			if(spi_open(_basePort, flag) == SPI_STATUS_OK) {
				_ret_status = pdPASS;
			}
		break;

		default: break;
	}


	return _ret_status;
}


uint8_t spi_io_close(io_port_t spiPort)
{
	uint8_t _ret_status = pdFAIL;
	SPI_port_t _basePort;

	switch(spiPort) {
		case IOP_SPI1:
		case IOP_SPI2:
		case IOP_SPI3:
			_basePort = spiPort - IOP_SPI1;
			spi_close(_basePort);
			_ret_status = pdPASS;
		break;

		default: break;
	}

	return _ret_status;
}


uint8_t spi_io_write(io_port_t spiPort, const void *pBuf, uint32_t size, io_rw_flag_t flag)
{
	uint8_t _ret_status = pdFAIL;
	SPI_port_t _basePort;


	switch(spiPort) {
		case IOP_SPI1:
		case IOP_SPI2:
		case IOP_SPI3:
			_basePort = spiPort - IOP_SPI1;
			switch(flag) {
				case IORWF_BYTE_ORDER:
					if (spi_write_byte(_basePort, pBuf, size) == SPI_STATUS_OK) {
						_ret_status = pdPASS;
					}
				break;

				default: break;
			}
		break;


		default: break;
	}

	return _ret_status;
}


uint32_t spi_io_read(io_port_t spiPort, void *pBuf, uint32_t size, io_rw_flag_t flag)
{
	uint32_t _recv_count = 0;
	SPI_port_t _basePort;

	switch(spiPort) {
		case IOP_SPI1:
		case IOP_SPI2:
		case IOP_SPI3:
			_basePort = spiPort - IOP_SPI1;
			switch(flag) {
				case IORWF_BYTE_ORDER:
					spi_read_byte(_basePort, pBuf, size, &_recv_count);
				break;

				default: break;
			}
		break;

		default: break;
	}

	return _recv_count;
}

